#pragma once
#include <functional>
#include <signal.h>
#include <unistd.h>
#include "socket.hpp"

using func_t = std::function<std::string(std::string &)>;

class TcpServer
{
public:
    TcpServer(func_t func, uint16_t port = 8080)
        : _port(port), _func(func)
    {
    }

    void Init()
    {
        // 1、创建socket
        _socket.Socket();
        // 2、bind
        _socket.Bind(_port);
        // 3、listen
        _socket.Listen();

        lg(Info, "server running!");
    }

    void Run()
    {
        signal(SIGCHLD, SIG_IGN); // 这两句复习的时候要着重看一下
        signal(SIGPIPE, SIG_IGN);

        // accept
        while (true)
        {
            std::string ip;
            uint16_t port;
            int newfd = _socket.Accept(&ip, &port);
            if (newfd < 0)
            {
                lg(Warning, "accept error %d, strerror %s", errno, strerror(errno));
                continue;
            }
            lg(Info, "accept success");

            if (fork() == 0) // 子进程
            {
                // 提供服务
                _socket.Close();
                std::string recv_package;

                while (true)
                {
                    // 接收客户端发来的request，报文
                    char inbuffer[1024];
                    ssize_t n = read(newfd, inbuffer, sizeof(inbuffer));

                    if (n > 0)
                    {
                        inbuffer[n] = 0;

                        recv_package += inbuffer; // 服务器接收到的报文
                        std::cout << "request: \n"
                                  << recv_package << std::endl;

                        while (true)
                        {
                            std::string send_package = _func(recv_package); // 交给这个函数进行处理和计算
                            if (send_package.empty())
                                break;
                            std::cout << "response: \n"
                                      << send_package << std::endl;
                            std::cout << recv_package << std::endl;

                            write(newfd, send_package.c_str(), send_package.size()); // 给客户端返回报文
                        }
                    }
                    else if (n == 0)
                        break;
                    else
                        break;
                }
                exit(0);
            }
            close(newfd);
        }
    }

    ~TcpServer()
    {
    }

private:
    uint16_t _port;
    int _listen_sockfd;
    Sock _socket;
    func_t _func;
};